[[...path]].page.tsx 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import React from 'react';
  2. import {
  3. NextPage, GetServerSideProps, GetServerSidePropsContext,
  4. } from 'next';
  5. import { useTranslation } from 'next-i18next';
  6. import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
  7. import dynamic from 'next/dynamic';
  8. import { useRouter } from 'next/router';
  9. import AdminCustomizeContainer from '~/client/services/AdminCustomizeContainer';
  10. import { CrowiRequest } from '~/interfaces/crowi-request';
  11. import PluginUtils from '~/server/plugins/plugin-utils';
  12. import ConfigLoader from '~/server/service/config-loader';
  13. import {
  14. useCurrentUser, /* useSearchServiceConfigured, */ useIsAclEnabled, useIsMailerSetup, useIsSearchServiceReachable, useSiteUrl,
  15. } from '~/stores/context';
  16. import {
  17. CommonProps, getServerSideCommonProps, useCustomTitle, getNextI18NextConfig,
  18. } from '../utils/commons';
  19. // import { useEnvVars } from '~/stores/admin-context';
  20. const AdminHome = dynamic(() => import('../../components/Admin/AdminHome/AdminHome'), { ssr: false });
  21. const AppSettingsPageContents = dynamic(() => import('../../components/Admin/App/AppSettingsPageContents'), { ssr: false });
  22. const SecurityManagementContents = dynamic(() => import('../../components/Admin/Security/SecurityManagementContents'), { ssr: false });
  23. const MarkDownSettingContents = dynamic(() => import('../../components/Admin/MarkdownSetting/MarkDownSettingContents'), { ssr: false });
  24. const CustomizeSettingContents = dynamic(() => import('../../components/Admin/Customize/Customize'), { ssr: false });
  25. const DataImportPageContents = dynamic(() => import('../../components/Admin/ImportData/ImportDataPageContents'), { ssr: false });
  26. const ExportArchiveDataPage = dynamic(() => import('../../components/Admin/ExportArchiveDataPage'), { ssr: false });
  27. const NotificationSetting = dynamic(() => import('../../components/Admin/Notification/NotificationSetting'), { ssr: false });
  28. const SlackIntegration = dynamic(() => import('../../components/Admin/SlackIntegration/SlackIntegration'), { ssr: false });
  29. const LegacySlackIntegration = dynamic(() => import('../../components/Admin/LegacySlackIntegration/LegacySlackIntegration'), { ssr: false });
  30. const UserManagement = dynamic(() => import('../../components/Admin/UserManagement'), { ssr: false });
  31. const UserGroupPage = dynamic(() => import('../../components/Admin/UserGroup/UserGroupPage'), { ssr: false });
  32. const ElasticsearchManagement = dynamic(() => import('../../components/Admin/ElasticsearchManagement/ElasticsearchManagement'), { ssr: false });
  33. // named export
  34. const AuditLogManagement = dynamic(() => import('../../components/Admin/AuditLogManagement').then(module => module.AuditLogManagement));
  35. const AdminLayout = dynamic(() => import('../../components/Layout/AdminLayout'), { ssr: false });
  36. const pluginUtils = new PluginUtils();
  37. type Props = CommonProps & {
  38. currentUser: any,
  39. nodeVersion: string,
  40. npmVersion: string,
  41. yarnVersion: string,
  42. installedPlugins: any,
  43. envVars: any,
  44. isAclEnabled: boolean,
  45. isSearchServiceConfigured: boolean,
  46. isSearchServiceReachable: boolean,
  47. isMailerSetup: boolean,
  48. siteUrl: string,
  49. };
  50. const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
  51. const { t } = useTranslation('admin');
  52. const router = useRouter();
  53. const path = router.query.path || 'home';
  54. const name = Array.isArray(path) ? path[0] : path;
  55. const adminPagesMap = {
  56. home: {
  57. title: useCustomTitle(props, t('Wiki Management Home Page')),
  58. component: <AdminHome
  59. nodeVersion={props.nodeVersion}
  60. npmVersion={props.npmVersion}
  61. yarnVersion={props.yarnVersion}
  62. installedPlugins={props.installedPlugins}
  63. />,
  64. },
  65. app: {
  66. title: useCustomTitle(props, t('App Settings')),
  67. component: <AppSettingsPageContents />,
  68. },
  69. security: {
  70. title: useCustomTitle(props, t('security_settings')),
  71. component: <SecurityManagementContents />,
  72. },
  73. markdown: {
  74. title: useCustomTitle(props, t('Markdown Settings')),
  75. component: <MarkDownSettingContents />,
  76. },
  77. customize: {
  78. title: useCustomTitle(props, t('Customize Settings')),
  79. component: <CustomizeSettingContents />,
  80. },
  81. importer: {
  82. title: useCustomTitle(props, t('Import Data')),
  83. component: <DataImportPageContents />,
  84. },
  85. export: {
  86. title: useCustomTitle(props, t('Export Archive Data')),
  87. component: <ExportArchiveDataPage />,
  88. },
  89. notification: {
  90. title: useCustomTitle(props, t('Notification Settings')),
  91. component: <NotificationSetting />,
  92. },
  93. 'global-notification': {
  94. title: '',
  95. component: <>global-notification</>,
  96. },
  97. 'slack-integration': {
  98. title: useCustomTitle(props, t('slack_integration')),
  99. component: <SlackIntegration />,
  100. },
  101. 'slack-integration-legacy': {
  102. title: useCustomTitle(props, t('Legacy_Slack_Integration')),
  103. component: <LegacySlackIntegration />,
  104. },
  105. users: {
  106. title: useCustomTitle(props, t('User_Management')),
  107. component: <UserManagement />,
  108. },
  109. 'user-groups': {
  110. title: useCustomTitle(props, t('UserGroup Management')),
  111. component: <UserGroupPage />,
  112. },
  113. search: {
  114. title: useCustomTitle(props, t('Full Text Search Management')),
  115. component: <ElasticsearchManagement />,
  116. },
  117. 'audit-log': {
  118. title: useCustomTitle(props, t('AuditLog')),
  119. component: <AuditLogManagement />,
  120. },
  121. };
  122. const content = adminPagesMap[name];
  123. const title = content.title;
  124. useCurrentUser(props.currentUser != null ? JSON.parse(props.currentUser) : null);
  125. useIsMailerSetup(props.isMailerSetup);
  126. // useSearchServiceConfigured(props.isSearchServiceConfigured);
  127. useIsSearchServiceReachable(props.isSearchServiceReachable);
  128. useIsAclEnabled(props.isAclEnabled);
  129. useSiteUrl(props.siteUrl);
  130. // useEnvVars(props.envVars);
  131. const adminCustomizeContainer = new AdminCustomizeContainer();
  132. const injectableContainers = [
  133. // adminAppContainer,
  134. // adminImportContainer,
  135. // adminHomeContainer,
  136. adminCustomizeContainer,
  137. // adminUsersContainer,
  138. // adminExternalAccountsContainer,
  139. // adminNotificationContainer,
  140. // adminSlackIntegrationLegacyContainer,
  141. // adminMarkDownContainer,
  142. // adminUserGroupDetailContainer,
  143. ];
  144. return (
  145. <AdminLayout title={title} selectedNavOpt={name} injectableContainers={injectableContainers}>
  146. {content.component}
  147. </AdminLayout>
  148. );
  149. };
  150. function injectServerConfigurations(context: GetServerSidePropsContext, props: Props): void {
  151. const req: CrowiRequest = context.req as CrowiRequest;
  152. const { crowi } = req;
  153. const { mailService } = crowi;
  154. props.isMailerSetup = mailService.isMailerSetup;
  155. }
  156. /**
  157. * for Server Side Translations
  158. * @param context
  159. * @param props
  160. * @param namespacesRequired
  161. */
  162. async function injectNextI18NextConfigurations(context: GetServerSidePropsContext, props: Props, namespacesRequired?: string[] | undefined): Promise<void> {
  163. const nextI18NextConfig = await getNextI18NextConfig(serverSideTranslations, context, namespacesRequired);
  164. props._nextI18Next = nextI18NextConfig._nextI18Next;
  165. }
  166. export const getServerSideProps: GetServerSideProps = async(context: GetServerSidePropsContext) => {
  167. const req: CrowiRequest = context.req as CrowiRequest;
  168. const { crowi } = req;
  169. const {
  170. appService, searchService, aclService,
  171. } = crowi;
  172. const { user } = req;
  173. const result = await getServerSideCommonProps(context);
  174. // check for presence
  175. // see: https://github.com/vercel/next.js/issues/19271#issuecomment-730006862
  176. if (!('props' in result)) {
  177. throw new Error('invalid getSSP result');
  178. }
  179. const props: Props = result.props as Props;
  180. if (user != null) {
  181. // props.currentUser = JSON.stringify(user.toObject());
  182. props.currentUser = JSON.stringify(user);
  183. }
  184. injectServerConfigurations(context, props);
  185. injectNextI18NextConfigurations(context, props, ['admin']);
  186. props.siteUrl = appService.getSiteUrl();
  187. props.nodeVersion = crowi.runtimeVersions.versions.node ? crowi.runtimeVersions.versions.node.version.version : null;
  188. props.npmVersion = crowi.runtimeVersions.versions.npm ? crowi.runtimeVersions.versions.npm.version.version : null;
  189. props.yarnVersion = crowi.runtimeVersions.versions.yarn ? crowi.runtimeVersions.versions.yarn.version.version : null;
  190. props.installedPlugins = pluginUtils.listPlugins();
  191. props.envVars = await ConfigLoader.getEnvVarsForDisplay(true);
  192. props.isAclEnabled = aclService.isAclEnabled();
  193. props.isSearchServiceConfigured = searchService.isConfigured;
  194. props.isSearchServiceReachable = searchService.isReachable;
  195. return {
  196. props,
  197. };
  198. };
  199. export default AdminMarkdownSettingsPage;